package com.github.fuse.handler;

import com.github.fuse.annotation.Default;
import com.github.fuse.entity.AopExecute;

import javax.annotation.PostConstruct;
import java.lang.annotation.Annotation;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author: wangdejun
 * @create: 2019-10-17 20:21
 **/
public abstract class AbstractFuseHandler<T extends Annotation> implements FuseHandler<T> {

    private static final Map<Class<? extends Annotation>, FuseHandler> fuseHandlerMap = new ConcurrentHashMap<>();

    public static final FuseHandler getHandler(Annotation annotation) {
        Class<? extends Annotation> clazz = Default.class;
        if (annotation != null) {
            clazz = annotation.annotationType();
        }
        FuseHandler fuseHandler = fuseHandlerMap.get(clazz);
        return Optional.ofNullable(fuseHandler).orElseThrow(() -> new RuntimeException("熔断类型不存在"));
    }

    @PostConstruct
    public void initHandler() {
        fuseHandlerMap.put(getType(), this);
    }

    public abstract Class<? extends Annotation> getType();

    @Override
    public Object handler(AopExecute aopExecute, T t) throws Throwable {
        try {
            return doHandler(aopExecute, t);
        } catch (Throwable e) {
            return fuseMethod(e, aopExecute, t);
        }

    }

    public abstract Object doHandler(AopExecute aopExecute, T t) throws Throwable;

    public abstract Object fuseMethod(Throwable e, AopExecute aopExecute, T t) throws Throwable;
}
